package com.mybatis.boost.domain.page;

import com.mybatis.boost.domain.sort.Sort;

import javax.annotation.Nonnull;

/**
 * Abstract interface for pagination information.
 *
 * @author jearton
 * @since 2017/2/15
 */
public interface Pageable {

    /**
     * Returns the page to be returned.
     *
     * @return the page to be returned.
     */
    int getPageNumber();

    /**
     * Returns the number of items to be returned.
     *
     * @return the number of items of that page
     */
    int getPageSize();

    /**
     * Returns the offset to be taken according to the underlying page and page size.
     *
     * @return the offset to be taken
     */
    default int getOffset() {
        return PageUtil.getOffset(getFirstPageNumber(), getPageNumber(), getPageSize());
    }

    /**
     * Returns the sorting parameters.
     */
    Sort getSort();

    /**
     * 页码是否从1开始
     */
    boolean isPageNumberOneIndexed();

    default int getFirstPageNumber() {
        return PageUtil.getFirstPageNumber(isPageNumberOneIndexed());
    }

    /**
     * 是否查询count
     */
    default boolean isQueryCount() {
        return true;
    }

    /**
     * 是否纠正分页边界错误，比如当page<1时，自动设置page=1
     * <p>
     * 不合法的分页参数情况（如果fixEdge=false，则前3个应抛异常）：
     * 1.page < first_page_number
     * 2.size < 1
     * 3.size > max_page_size
     * 4.page > last_page_number（做count查询后才能发现）
     */
    default boolean isFixEdge() {
        return true;
    }

    @Nonnull
    Pageable jumpTo(int page);

    @Nonnull
    default Pageable copy() {
        return jumpTo(getPageNumber());
    }
}
